import entity.Employee;
import func.FuncPredicate;
import func.impl.FilterEmployeeByAge;
import func.impl.FilterEmployeeBySalary;
import org.junit.Test;

import java.util.*;

/**
 * Created by VincentZee on 2019/3/2
 */
public class TestLambda01 {
    // 使用匿名内部类
    @Test
    public void test01() {
        Comparator<String> comparator = new Comparator<String>() {
            public int compare(String o1, String o2) {
                return Integer.compare(o1.length(), o2.length());
            }
        };

        TreeSet<String> treeSet = new TreeSet<>(comparator);


        TreeSet<String> treeSet1 = new TreeSet<>(new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return Integer.compare(o1.length(), o2.length());
            }
        });
    }

    // 使用Lambda表达式
    @Test
    public void test02() {
        Comparator<String> comparator = (x, y) -> Integer.compare(x.length(), y.length());
        // Comparator<String> comparator1 = Comparator.comparingInt(String::length);
        TreeSet<String> treeSet = new TreeSet<>(comparator);
    }

    private List<Employee> emps = Arrays.asList(
            new Employee(101, "张三", 18, 9999.99),
            new Employee(102, "李四", 59, 6666.66),
            new Employee(103, "王五", 28, 3333.33),
            new Employee(104, "赵六", 8, 7777.77),
            new Employee(105, "田七", 38, 5555.55)
    );

    // 需求：获取公司中年龄小于 35 的员工信息
    public List<Employee> filterEmployeeByAge(List<Employee> employees) {
        List<Employee> employeeList = new ArrayList<>();
        for (Employee employee : employees) {
            if (employee.getAge() < 35) {
                employeeList.add(employee);
            }
        }
        return employeeList;
    }

    @Test
    public void test03() {
        List<Employee> list = filterEmployeeByAge(emps);

        for (Employee employee : list) {
            System.out.println(employee);
        }
    }

    // 需求：获取公司中工资大于 5000 的员工信息
    public List<Employee> filterEmployeeBySalary(List<Employee> employees) {
        List<Employee> list = new ArrayList<>();

        for (Employee emp : employees) {
            if (emp.getSalary() >= 5000) {
                list.add(emp);
            }
        }

        return list;
    }

    // 优化方式一：策略设计模式
    public List<Employee> filterEmployee(List<Employee> employees, FuncPredicate<Employee> funcPredicate) {
        List<Employee> employeeList = new ArrayList<>();
        for (Employee employee : employees) {
            if (funcPredicate.test(employee)) {
                employeeList.add(employee);
            }
        }
        return employeeList;
    }

    @Test
    public void test04() {
        List<Employee> employeeList = filterEmployee(emps, new FilterEmployeeByAge());
        for (Employee employee : employeeList) {
            System.out.println(employee);
        }

        List<Employee> employeeList1 = filterEmployee(emps, new FilterEmployeeBySalary());
        for (Employee employee : employeeList1) {
            System.out.println(employee);
        }
    }

    // 优化方式二：匿名内部类
    @Test
    public void test05() {
        List<Employee> employeeList = filterEmployee(emps, new FuncPredicate<Employee>() {
            @Override
            public boolean test(Employee employee) {
                return employee.getId() <= 103;
            }
        });
        for (Employee employee : employeeList) {
            System.out.println(employee);
        }
    }

    // 优化方式三：Lambda 表达式
    @Test
    public void test06() {
        List<Employee> employeeList = filterEmployee(emps, (e) -> e.getId() <= 103);
        employeeList.forEach(System.out::println);

        List<Employee> employeeList1 = filterEmployee(emps, (e) -> e.getSalary() >= 5000);
        employeeList1.forEach(System.out::println);
    }

    // 优化方式四：Stream API
    @Test
    public void test07() {
        emps.stream().filter((e) -> e.getId() <= 103).forEach(System.out::println);

        System.out.println("---");

        emps.stream().map(Employee::getName).limit(3).sorted().forEach(System.out::println);
    }
}
